﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls.Primitives;
using System.Windows;
using System.Windows.Automation;
using System.Threading;
using System.Threading.Tasks;
using InnovTech.Wpf.Automation;

namespace AutomationLib
{
    public class AutoTestHelper
    {
        #region fields
        /// <summary>
        /// Represents the instance of Type <see cref="AutoTestSTAHelper"/> to create a STA Thread for the UI-Testing.
        /// </summary>
        private AutoTestSTAHelper _staHelper;

        private UIAutomaton _automaton = new UIAutomaton(AutoTestContainer.TestWindowName);

        #endregion fields

        #region Properties
        /// <summary>
        /// Gets the current UI to test.
        /// </summary>
        public FrameworkElement CurrentTestUI { get; protected set; }

        #endregion Properties

        #region methods

        #region private

        private Action CreateTestLogic(FrameworkElement ancestor, Action logic, object viewModel = null)
        {
            if (viewModel != null)
                ancestor.DataContext = viewModel;

            Action testLogic = new Action(() =>
            {
                Application app = new Application();
                Window container = AutoTestContainer.CreateTestContainer(ancestor);
                app.Startup += (sender, args) =>
                {
                    StartAutomationLogic(logic, app, TaskScheduler.FromCurrentSynchronizationContext());
                };

                container.Show();
                app.Run();
            });

            return testLogic;
        }

        private void StartAutomationLogic(Action logic, Application app, TaskScheduler appScheduler)
        {
            Task.Factory.StartNew(() =>
            {
                Thread.Sleep(1000);
                logic();
                Thread.Sleep(1000);
            }).ContinueWith(task =>
            {
                app.Shutdown();
            }, appScheduler);
        }

        #endregion private

        #endregion methods
        

        public void ProcessButtonClick(string buttonId)
        {
            _automaton.ProcessButtonClick(buttonId);
        }

        public void ProcessComboBoxSelection(string comboBoxId, String itemText)
        {
            _automaton.ProcessComboBoxSelection(comboBoxId, itemText);
        }

        public void ProcessTextInput(string id, string value)
        {
            _automaton.ProcessTextInput(id, value);
        }

        public void ProcessRadioButtonSelection(string id)
        {
            _automaton.ProcessRadioButtonSelection(id);
        }

        /// <summary>
        /// Processes the selection of a <see cref="Selector"/>. 
        /// </summary>
        /// <param name="selectorId">The value of the property <see cref="FrameworkElement.Name"/>of the <see cref="Selector"/> to test.</param>
        /// <param name="itemText">The Text that is shown currently by the <see cref="Selector"/>. 
        /// It can be the 
        /// 1. <see cref="ListBox.SelectedItem"/>, 
        /// 2. <see cref="ComboBox.SelectedItem"/> or 
        /// 3. <see cref="TabControl.SelectedItem.Header"/></param>
        public void ProcessSelection(string selectorId, string itemText)
        {
            _automaton.ProcessSelection(selectorId, itemText);
        }

        public void ProcessToggle(string controlId)
        {
            _automaton.ProcessToggle(controlId);
        }

        public void RunUITest(Func<FrameworkElement> GetTestUIs, Action testLogic)
        {
            _staHelper = new AutoTestSTAHelper();
            _staHelper.RunTest(() =>
            {
                CurrentTestUI = GetTestUIs();
                CreateTestLogic(CurrentTestUI, testLogic)();
            });
        }

        

        

        #region old

        public void RunTest(Action testAction)
        {
            _staHelper = new AutoTestSTAHelper();
            _staHelper.RunTest(testAction);
        }

        #endregion

        

        
    }
}
